package com.yang.bean.beanfactory.impl;

import com.yang.bean.beanDefinition.BeanDefinition;
import com.yang.bean.beanDefinition.PropertyValue;
import com.yang.bean.beanDefinition.RuntimeBeanReference;
import com.yang.bean.beanDefinition.TypeStringValue;
import com.yang.bean.beanfactory.AutowireCapableBeanFactory;
import com.yang.bean.util.ReflectionUtils;

import java.util.List;

/**
 * @Description:
 * @author: Yang Qiang
 * @create: 2021-11-07 18:16
 */
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
    @Override
    public Object createBean(Class<?> type) {
        return null;
    }

    /**
     * 创建一个对象
     * @param beanDefinition
     * @return
     */
    @Override
    protected Object createBean(BeanDefinition beanDefinition) {
        // 得到class的name
        String className = beanDefinition.getClassName();
        // 将className转化为Class类型
        Class<?> cls = resolveClassName(className);
        if (cls == null){
            return null;
        }

        // 实例化
        Object singleton = createBeanInstance(cls);

        // 填充属性, 也就是填充响应的property
        populateBean(singleton, beanDefinition);

        // 初始化-> 进行后置处理器, init-method, 初始化方法等等

        return singleton;
    }

    protected void populateBean(Object singleton, BeanDefinition beanDefinition){
        List<PropertyValue> propertyValues = beanDefinition.getPropertyValues();
        if (propertyValues == null || propertyValues.size() == 0){
            return;
        }

        for (PropertyValue propertyValue : propertyValues) {
            String name = propertyValue.getName();
            // value有两种类型, 一种是value, 一总是ref
            Object value = propertyValue.getValue();
            Object valueToRef = null;

            if (value instanceof RuntimeBeanReference){
                // 如果是ref标签所对应的类, 从容器中获取
                RuntimeBeanReference reference = (RuntimeBeanReference) value;
                valueToRef = getBean(reference.getRef());

            }else if (value instanceof TypeStringValue){
                TypeStringValue tsv = (TypeStringValue)value;
                String val = tsv.getValue();
                Class<?> type = tsv.getTargetType();
                // 判断value的基本类型
                if (type == Integer.class){
                    valueToRef = Integer.parseInt(val);
                }else if (type == String.class){
                    valueToRef = val;
                }else if (type == Long.class){
                    valueToRef = Long.parseLong(val);
                }else {
                    // 其他类型的转换.....省略
                }
            }

            // 对属性进行赋值
            ReflectionUtils.setProperty(singleton, name, valueToRef);
        }
    }

    protected Object createBeanInstance(Class<?> cls){
        // 封装反射工具类创建对象
        return ReflectionUtils.creatBean(cls);
    }

    protected Class<?> resolveClassName(String className){
        // 通过反射创建
        try {
            return Class.forName(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

}
